/**
Vue Router 是 Vue.js 的官方路由管理器，用于构建单页面应用（SPA）。在 Vue 3 中，Vue Router 提供了灵活的路由配置和强大的导航功能。
  1. 安装 Vue Router
  首先，需要安装 Vue Router。可以通过 npm 或 yarn 安装：
  npm install vue-router@4

  2. 创建路由实例
  在 Vue 3 中，创建路由实例的基本步骤如下：
   1. 定义路由
  路由配置是一个数组，每个路由对象都包含路径和组件。
  import { createRouter, createWebHistory } from 'vue-router';
  import Home from './components/Home.vue';
  import About from './components/About.vue';

  const routes = [
    { path: '/', component: Home },
    { path: '/about', component: About }
  ];
   2. 创建路由实例

  使用  `createRouter`  创建路由实例，并指定路由模式（如  `createWebHistory` ）。
  const router = createRouter({
    history: createWebHistory(),
    routes
  });
  3. 在应用中使用 Vue Router
  将路由实例传递给 Vue 应用。
  import { createApp } from 'vue';
  import App from './App.vue';

  const app = createApp(App);
  app.use(router); // 使用 Vue Router
  app.mount('#app');
  4. 路由视图

  在组件模板中使用  `<router-view>`  来渲染匹配的组件。
  vue
  <template>
    <div>
      <router-view></router-view>
    </div>
  </template>
  5. 导航
   1. 编程式导航
  使用  `router.push`  或  `router.replace`  方法进行编程式导航。
  router.push('/about'); // 导航到 About 页面
   2. 声明式导航
  使用  `<router-link>`  组件进行声明式导航。
  vue
  <template>
    <div>
      <router-link to="/">Home</router-link>
      <router-link to="/about">About</router-link>
    </div>
  </template>
  6. 路由守卫
  路由守卫用于控制路由的访问权限，可以在路由配置中定义全局守卫、路由独享守卫和组件内守卫。
   示例：全局守卫
  router.beforeEach((to, from) => {
    // 在路由跳转前执行
  });
  7. 动态路由和嵌套路由
   1. 动态路由
  可以使用动态参数定义路由。
  { path: '/user/:id', component: User }
   2. 嵌套路由
  支持嵌套路由，可以在子路由中定义子组件。
  const routes = [
    {
      path: '/about',
      component: About,
      children: [
        { path: 'team', component: Team },
        { path: 'company', component: Company }
      ]
    }
  ];
  8. 路由元信息
  可以在路由配置中添加  `meta`  字段，用于存储路由的元信息，如权限、标题等。
  { path: '/about', component: About, meta: { requiresAuth: true } }
  总结
  Vue 3 Router 是构建单页面应用的强大工具，提供了灵活的路由配置、导航功能和路由守卫。通过理解和掌握 Vue Router 的基本用法，可以有效地管理应用的页面导航和访问控制，提高用户体验。 
 */
import { createRouter, createWebHistory } from "vue-router";

// 创建一个路由: 定义路由规则
const router = createRouter({
  // history: 路由模式
  history: createWebHistory(),
  // routes: 路由规则
  routes: [
    {
      path: "/",
      redirect: "/home",
    },
    {
      path: "/home",
      name: "home",
      component: () => import("../views/home/Home.vue"),
      meta: {
        title: "首页",
        name: "home-meta",
      },
      children: [
        {
          path: "/home",
          redirect: "/home/recommend",
        },
        {
          path: "recommend",
          component: () => import("../views/home/HomeRecommend.vue"),
        },
        {
          path: "ranking",
          component: () => import("../views/home/HomeRanking.vue"),
        },
      ],
    },
    {
      path: "/login",
      name: "login",
      component: () => import("../views/login/Login.vue"),
    },
    {
      path: "/about",
      name: "About",
      component: () => import("../views/about/About.vue"),
    },
    {
      path: "/user/:id",
      name: "User",
      component: () => import("../views/user/User.vue"),
    },
    {
      path: "/order",
      name: "Order",
      component: () => import("../views/order/Order.vue"),
    },
    {
      path: "/:pathMatch(.*)*",
      name: "NotFound",
      component: () => import("../views/404/NotFound.vue"),
    },
  ],
});

// 1. 路由动态管理
let isAdmin = true;
if (isAdmin) {
  router.addRoute({
    path: "/admin",
    name: "Admin",
    component: () => import("../views/admin/Admin.vue"),
  });

  router.addRoute("home", {
    path: "vip",
    component: () => import("../views/home/HomeVip.vue"),
  });
}

// 获取router中所有的映射路由对象
console.log(router.getRoutes());

// 2. 路由导航守卫
// 2.1 beforeEach: 全局前置守卫
// 需求: 进入到订单(order)页面时, 判断用户是否登录(isLogin -> localStorage保存token)
// 情况一: 用户没有登录, 那么跳转到登录页面, 进行登录的操作
// 情况二: 用户已经登录, 那么直接进入到订单页面
// 有next: 函数, 必须调用, 否则路由导航会中断
router.beforeEach((to, from) => {
  // to: 即将要进入的目标路由对象
  // from: 当前导航正要离开的路由
  // next: 函数, 必须调用, 否则路由导航会中断
  // 1.进入到任何别的页面时, 都跳转到login页面
  // if (to.path !== "/login") {
  //   return "/login"
  // }

  // 2.进入到订单页面时, 判断用户是否登录
  const token = localStorage.getItem("token");
  if (to.path === "/order" && !token) {
    return "/login";
  }
});

// 后置路由守卫: 在路由跳转后执行
router.afterEach((to, from) => {
  console.log("后置路由守卫");
});

export default router;
